// index.ts
import axios from "axios";
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
import { Toast } from 'tdesign-mobile-vue';
// import * as x2js from 'x2js'

type Result<T> = {
  code: number;
  message: string;
  result: T;
};


export class Request {
  instance: AxiosInstance;
  baseConfig: AxiosRequestConfig = { baseURL: "", timeout: 120000 };

  constructor(config: AxiosRequestConfig,questOriginType?:string) {
    this.instance = axios.create(Object.assign(this.baseConfig, config));

    //处理业务请求头
    this.instance.interceptors.request.use(
      (config: AxiosRequestConfig) => {
        // const token = localStorage.getItem("token") as string
        // if(token) {
        //   config.headers!.Authorization = token;
        // }
        let reqData = {
          url:config.baseURL+config.url,
          data:config.data
        }
        window.electronApi.logger('info', JSON.stringify(reqData))

        if(questOriginType=='hisRequest'){
          console.log('config.data',config.data)
          const {Fid,query}=config.data
          // let sendXml = `<?xml version="1.0" encoding="GBK" standalone="yes"?>
          // <ROOT>
          //     <HEAD>
          //         <cpytrnflow>049212156463</cpytrnflow>
          //         <hosno></hosno>
          //         <ibsinfo></ibsinfo>
          //         <ibslocdate></ibslocdate>
          //         <locdate>20230101</locdate>
          //         <loctime>212156</loctime>
          //         <mgid>-1</mgid>
          //         <msgtype>0200</msgtype>
          //         <procode>${Fid}</procode>
          //         <refnum></refnum>
          //     </HEAD>
          //     <BODY>
          //       ${query}
          //     </BODY>
          // </ROOT>
          //     `

          let sendXml:any = '<?xml version="1.0" encoding="GBK" standalone="yes"?>\n' +
          '<ROOT>\n' +
              '<HEAD>\n' +
                  '<cpytrnflow>049212156463</cpytrnflow>\n' +
                  '<hosno></hosno>\n' +
                  '<ibsinfo></ibsinfo>\n' +
                  '<ibslocdate></ibslocdate>\n' +
                  '<locdate>20230101</locdate>\n' +
                  '<loctime>212156</loctime>\n' +
                  '<mgid>-1</mgid>\n' +
                  '<msgtype>0200</msgtype>\n' +
                  '<procode>'+Fid+'</procode>\n' +
                  '<refnum></refnum>\n' +
              '</HEAD>\n' +
              '<BODY>\n' +  query+
              '</BODY>\n' +
          '</ROOT>';

          // console.log('sendXml',sendXml)
          // console.log('sendXml1111',JSON.stringify(sendXml))

          // sendXml  = JSON.stringify(sendXml);
          // sendXml  = sendXml.replace(/\s/g,'');
          console.log('sendXml:',sendXml);
          window.electronApi.logger('info', sendXml)

          let data = {args:{
            port: 2018,
            ip: 'localhost',
            sendXml
          }}
          config.data=data
        }

        return config;
      },
      (err: any) => {
        // 请求错误，这里可以用全局提示框进行提示
        return Promise.reject(err);
      }
    );

    this.instance.interceptors.response.use(
      (res: AxiosResponse) => {
        // 直接返回res，当然你也可以只返回res.data
        // 系统如果有自定义code也可以在这里处理
        // return res.data;
        //打印所有响应
        window.electronApi.logger('info', JSON.stringify(res)) 
        let resData=res.data.data||res.data.result
        if(questOriginType=='hisRequest'){
          console.log('resData',JSON.parse(resData))
          // const x2jsone = new x2js()
          // const xml = x2jsone.xml2js(resData)
          // 发起时填-1，响应成功为200，无数据为204，其他为失败（比如F152，如果没有建档是204，如果读卡错误是500）
          const xml = JSON.parse(resData)
          const {mgid,ibsinfo}=xml['ROOT']['HEAD']
          if(mgid=='200'){
            const body =xml['ROOT']['BODY']
            return body
          }else if(mgid=='204'){  
            return null  //没有数据返回null，系统异常返回是undefined 以此区分            
          }else{   //mgid 500
            const info = ibsinfo||'系统异常'
            Toast(info || '系统异常')
            window.electronApi.logger('error', JSON.stringify(resData))
            return;
          }
        }

        if(res.config.url=='/heren.com/payment/jiaXingSEPaymentHandler/readCrad'){ //读卡接口不处理
          return res.data
        }
        if (res.data.code === '0'||res.data.code === 'SUCCESS'||res.data.resultCode === '0') {
          return resData;
        } else {
            if(res.config.url=='/service-pat-order/rest/hr-auth/get-login-token'){  //未注册统一认证
              return res.data
            }
            const info=res.data.message ||res.data.descMessage|| '系统异常'
            Toast(info)
            window.electronApi.logger('error', JSON.stringify(res.data))
            return Promise.reject(res.data)
        }
      },
      (err: any) => {
        window.electronApi.logger('error', JSON.stringify(err))
        let message = "";
        switch (err.response?.status) {
          case 400:
            message = "请求错误(400)";
            break;
          case 401:
            message = "未授权，请重新登录(401)";
            // 这里可以做清空storage并跳转到登录页的操作
            break;
          case 403:
            message = "拒绝访问(403)";
            break;
          case 404:
            message = "请求出错(404)";
            break;
          case 408:
            message = "请求超时(408)";
            break;
          case 500:
            message = "服务器错误(500)";
            break;
          case 501:
            message = "服务未实现(501)";
            break;
          case 502:
            message = "网络错误(502)";
            break;
          case 503:
            message = "服务不可用(503)";
            break;
          case 504:
            message = "网络超时(504)";
            break;
          case 505:
            message = "HTTP版本不受支持(505)";
            break;
          default:
            message = `连接出错(${err.response.status})!`;
        }
        // 这里错误消息可以使用全局弹框展示出来
        // 比如element plus 可以使用 ElMessage
        // ElMessage({
        //   showClose: true,
        //   message: `${message}，请检查网络或联系管理员！`,
        //   type: "error",
        // });
        // 这里是AxiosError类型，所以一般我们只reject我们需要的响应即可
        return Promise.reject(err.response);
      }
    );
  }

  // 定义请求方法
  public request(config: AxiosRequestConfig): Promise<AxiosResponse> {
    return this.instance.request(config);
  }

  public get<T = any>(
    url: string,
    config?: AxiosRequestConfig
  ): Promise<AxiosResponse<Result<T>>> {
    return this.instance.get(url, config);
  }

  public post<T = any>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig
  ): Promise<AxiosResponse<Result<T>>> {
    return this.instance.post(url, data, config);
  }

  public put<T = any>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig
  ): Promise<AxiosResponse<Result<T>>> {
    return this.instance.put(url, data, config);
  }

  public delete<T = any>(
    url: string,
    config?: AxiosRequestConfig
  ): Promise<AxiosResponse<Result<T>>> {
    return this.instance.delete(url, config);
  }
}

// 默认导出Request实例
export default new Request({})

